package com.yeskery.nut.view;

import com.yeskery.nut.core.NutException;
import com.yeskery.nut.core.Request;
import com.yeskery.nut.core.Response;
import com.yeskery.nut.util.StringUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * 默认的后缀视图处理器
 * @author sprout
 * @version 1.0
 * 2022-07-02 13:58
 */
public class DefaultPostfixViewHandler implements PostfixViewHandler {

    /** 扩展分隔符 */
    private static final String EXTENSION_SEPARATOR = ".";

    /** 路径分隔符 */
    private static final String FOLDER_SEPARATOR = "/";

    /** 视图解析器Map */
    private final Map<String, ViewResolver> viewResolverMap = new HashMap<>();

    /** 全局前缀 */
    private String globalPrefix;

    /** 全局后缀 */
    private String globalPostfix;

    /**
     * 注册视图解析器
     * @param viewResolver 视图解析器
     */
    @Override
    public void registerViewResolver(ViewResolver viewResolver) {
        viewResolverMap.put(viewResolver.getPostfix(), viewResolver);
    }

    @Override
    public Collection<ViewResolver> getRegisteredViewResolvers() {
        return viewResolverMap.values();
    }

    /**
     * 设置全局前缀
     * @param globalPrefix 全局前缀
     */
    @Override
    public void setGlobalPrefix(String globalPrefix) {
        if (!globalPrefix.endsWith(FOLDER_SEPARATOR)) {
            globalPrefix = globalPrefix + FOLDER_SEPARATOR;
        }
        this.globalPrefix = globalPrefix;
    }

    /**
     * 设置全局后缀
     * @param globalPostfix 全局后缀
     */
    @Override
    public void setGlobalPostfix(String globalPostfix) {
        this.globalPostfix = globalPostfix;
    }

    @Override
    public void handle(ModelAndView modelAndView, Request request, Response response) {
        if (modelAndView == null || StringUtils.isEmpty(modelAndView.getView())) {
            throw new NutException("View Must Not Be Empty.");
        }
        String viewPath = modelAndView.getView();
        String postfix;
        if (modelAndView.getView().contains(EXTENSION_SEPARATOR)) {
            postfix = StringUtils.getFilenameExtension(modelAndView.getView());
        } else {
            postfix = globalPostfix;
            viewPath = viewPath + EXTENSION_SEPARATOR + globalPostfix;
        }
        if (StringUtils.isEmpty(postfix)) {
            throw new NutException("View Postfix Must Not Be Empty.");
        }

        ViewResolver viewResolver = viewResolverMap.get(postfix);
        if (viewResolver == null) {
            throw new NutException("View Postfix [" + postfix + "] Resolver Does Not Exist.");
        }

        if (!StringUtils.isEmpty(globalPrefix)) {
            viewPath = globalPrefix + viewPath;
        }

        View view;
        try {
            view = viewResolver.createView(viewPath, Locale.getDefault());
        } catch (Exception e) {
            throw new NutException("View Create Failure.", e);
        }
        try {
            view.render(modelAndView.getModel().toMap(), request, response);
        } catch (Exception e) {
            throw new NutException("View Render Failure.", e);
        }
    }
}
